﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "GcmpRenderingInterface.h"
#include "ElementId.h"
#include "Vector3d.h"

namespace gcmp
{
    class Matrix4d;
    struct Color;
    class Vector4d;
    class Vector3d;

    // 相机的状态
    struct CameraStatus
    {
        CameraStatus(const Vector3d& pos, const Vector3d& dir, const Vector3d& upDir) : Position(pos), Direction(dir), UpDirection(upDir) {};
        Vector3d Position;    // 相机位置
        Vector3d Direction;   // 相机方向
        Vector3d UpDirection; // 相机上方向
    };

    // 可以设置每个构件关键帧的状态，包括
    // 刚体变换、颜色、透明度、裁剪面、可见性
    class GCMP_RENDERING_INTERFACE_EXPORT IElementKeyFrame
    {
    public:
        /// \brief 创建一个构件的动画帧
        ///
        /// \return 创建出的动画帧
        static std::shared_ptr<IElementKeyFrame> CreateIElementKeyFrame();

        /// \brief 设置变换矩阵
        /// \param Matrix4d 变换矩阵
        virtual void SetTransform(const Matrix4d& transform) = 0;
        /// \brief  得到变换矩阵
        /// \return 若未设置返回空
        virtual const Matrix4d* GetTransform() const = 0;

        /// \brief 设置颜色
        /// 注：若还设置了SetTransparent，则color的透明度会被transparent覆盖
        /// \param color 颜色
        virtual void SetColor(const Color& color) = 0;
        /// \brief  得到颜色设置
        /// \return 若未设置返回空
        virtual const Color* GetColor() const = 0;

        /// \brief 设置透明度(淡入淡出效果)
        /// 会覆盖SetColor设置的透明度
        /// \param transparency 目标透明度，取值范围 [0.0,1.0]，0.0-完全透明，1.0-完全不透明
        virtual void SetTransparent(double tranparent) = 0;

        /// \brief  得到透明度设置
        /// \return 若未设置返回空
        virtual const double* GetTransparent() const = 0;

        /// \brief  设置裁剪面
        /// \param clipPlane 裁剪面参数
        virtual void SetClipPlane(const Vector4d& clipPlane) = 0;

        /// \brief  得到裁剪面设置
        /// \return 若未设置返回空
        virtual const Vector4d* GetClipPlane() const = 0;

        /// \brief  设置可见性
        /// \param isVisible 是否可见
        virtual void SetVisible(bool isVisible) = 0;

        /// \brief  得到可见性设置
        /// \return 若未设置返回空
        virtual const bool* GetVisible() const = 0;

        /// \brief 析构函数
        virtual ~IElementKeyFrame() = default;
    };


    class GCMP_RENDERING_INTERFACE_EXPORT IOneAnimationFrame
    {
    public:
        /// \brief 创建一帧动画       
        ///    包含相机状态以及各element的刚体变换、颜色、透明度、裁剪面、可见性等动作
        /// 
        /// \return 创建出的一帧动画  
        static OwnerPtr<IOneAnimationFrame> CreateOneAnimationFrame();

        /// 设置相机的姿态
        /// \param cameraStatus  相机姿态（包括位置、观察方向、上方向）
        virtual void SetCameraStatus(const CameraStatus& cameraStatus) = 0;

        /// 获取相机的姿态
        ///
        /// \return 相机姿态, 若没设置则返回空
        virtual const CameraStatus* GetCameraStatus() const = 0;

        /// 设置各Element的状态
        /// \param eleId  Element的id
        /// \param elementState  Element的动画动作
        virtual void SetElementKeyFrame(ElementId eleId, std::shared_ptr<IElementKeyFrame> elementState) = 0;

        /// 获取某个element的动画帧
        /// \param eleId  element的id
        /// \return element的动画帧,若未设置则返回空
        virtual IElementKeyFrame* GetElementKeyFrameFW(ElementId eleId) = 0;

        /// 获取某个element的动画帧
        /// \param eleId  element的id
        /// \return element的动画帧,若未设置则返回空
        virtual const IElementKeyFrame* GetElementKeyFrame(ElementId eleId) const = 0;

        /// 获取所有自定义动画Element的状态
        virtual const std::map<ElementId, std::shared_ptr<IElementKeyFrame>>& GetAllElementKeyFrames() const = 0;

        /// \brief 析构函数
        virtual ~IOneAnimationFrame() = default;
    };

}

